#ifndef CLIENT_HH
# define CLIENT_HH

# include <tools/utility.hh>
# include <request/type.hh>
# include <network/network-manager.hh>

# include <request/request.hh>

# include <boost/thread.hpp>
# include <boost/asio.hpp>
# include <boost/array.hpp>

# include <tbb/concurrent_queue.h>

# include "misc/database.hh"
# include "physic/object.hh"

# include "octree/octree.hh"

class RequestCreatorServer;
class GameThread;
class FpsThread;

using boost::asio::ip::tcp;

class Client
{
public:
  Client (tcp::socket* s, Database* db, GameThread* gt);
  ~Client ();

  void start ();

  void send_map (Octree* o);

  void fps_thread (FpsThread* t);

  //getters
  Database* database () const { return this->db_; }
  unsigned char pos_x () const { return pos_x_; }
  unsigned char pos_y () const { return pos_y_; }
  NetworkManager* nm () { return &nm_; }

  //setters
  void id (int newid) { id_ = newid; }
  void pos (unsigned char p_x, unsigned char p_y) { pos_x_ = p_x; pos_y_ = p_y; }

  //State
  GameMode::GameType mode () const;

  bool locked () const { return locked_; }
  void locked (bool val) { locked_ = val; }

protected:
  int id_;
  RequestCreatorServer* rcs_;

  unsigned char pos_x_;
  unsigned char pos_y_;

  NetworkManager nm_;
  Database* db_;
  boost::thread t_;
  boost::array<char, 500000> buf_;
  GameThread* gt_;

  FpsThread* fps_thread_;

  //flag
  bool locked_;
};

#endif /// !CLIENT_HH
